package cn.tedu.common.ex;

import lombok.Getter;

/**
 * API统一封装应答结果
 * 说明：此类不要修改，有扩展需求请咨询许凯834721446@qq.com
 *
 * @author xukai
 * @date 20200418
 */
@Getter
public class Result<T> {

    /**
     * 构造器私有，外界只可以调用统一返回类的方法，不可以直接创建
     */
    private Result() {}

    /**
     * 状态码
     */
    private int code;

    /**
     * 给客户端用于提示的消息
     */
    private String message;

    /**
     * 业务数据
     */
    private T data;

    /**
     * 通用返回成功(不带业务数据)
     * @return
     */
    public static <P> Result<P> success() {
        return new Result<P>()
                .setCode(ResultCodeEnum.SUCCESS.getCode())
                .setMessage(ResultCodeEnum.SUCCESS.getMessage());
    }

    /**
     * 通用返回成功(带业务数据)
     * @param data 业务数据
     * @return
     */
    public static <P> Result<P> success(P data) {
        return new Result<P>()
                .setCode(ResultCodeEnum.SUCCESS.getCode())
                .setMessage(ResultCodeEnum.SUCCESS.getMessage())
                .setData(data);
    }

    /**
     * 错误结果
     * @param resultCodeEnum 结果状态码枚举
     * @return
     */
    public static Result error(ResultCodeEnum resultCodeEnum) {
        return new Result()
                .setCode(resultCodeEnum.getCode())
                .setMessage(resultCodeEnum.getMessage());
    }

    /**
     * 错误结果
     * @param resultCodeEnum 结果状态码枚举
     * @return
     */
    public static Result error(ResultCodeEnum resultCodeEnum, String message) {
        return new Result()
                .setCode(resultCodeEnum.getCode())
                .setMessage(message);
    }

    /**----------------------------------使用链式编程，返回实例本身-------------------------------------*/
    /**
     * 自定义给前端用于提示的消息
     * @param message
     * @return
     */
    public Result setMessage(String message) {
        this.message = message;
        return this;
    }

    /**
     * 自定义状态码，私有不开放给调用者修改，只能用规定好的几种状态码
     * @param code
     * @return
     */
    private Result setCode(int code) {
        this.code = code;
        return this;
    }

    /**
     * 私有化设置业务数据
     * @param data
     * @return
     */
    private Result<T> setData(T data) {
        this.data = data;
        return this;
    }

    public void throwExceptionIfNotSuccess() {
        if (ResultCodeEnum.SUCCESS.getCode() != this.getCode()) {
            throw new ServiceException(ResultCodeEnum.PARAMETER_ERROR, this.getMessage());
        }
    }
}
